function uniqueArray<T>(array: Array<T>): T[] { 
  return Array.from(new Set(array));
}

const arr1 = [1, 2, 2, 3, 3, 4, 5];
const arr2 = ["a", "a", "b", "b"];

const arr3 = uniqueArray(arr1);
const arr4 = uniqueArray(arr2);
console.log(arr3);
console.log(arr4);

type User = {
  id: number,
  name: string,
  tel: string,
  address?: string
}

type ResultData<T> = {
  message: string,
  code: number,
  data?: T
}

type UserData = ResultData<User>;

const userResultData: UserData = {
  message: "成功",
  code: 200,
  data: {
    id: 1,
    name: "jack",
    tel: "1111",
    address:"北京"
  }
}

interface MyEvent<T> {
  target: T,
  type: string
}

type TimedEvent<T> = {
  event: MyEvent<T> 
  from: Date
  to: Date
}

const myEvent: MyEvent<HTMLButtonElement | null> = {
  target: document.querySelector("button"),
  type: "click"
}

const timeEvent: TimedEvent<HTMLDivElement | null> = {
  event: {
    target: document.querySelector("div"),
    type: "click"
  },
  from: new Date(),
  to: new Date()
}

function triggerEvent<T>(event: MyEvent<T>): void { 
  // todos...
}

triggerEvent({
  target: document.querySelector("span"),
  type: "click"
})

type Nullable<T> = T | null | undefined;

let str: Nullable<string> = null;
str = "hello";

let u: Nullable<User> = null;
u = {
  id: 1,
  name: "jack",
  tel: "1111",
  address:"北京"
}


// function filter<T>(arr:T[], callback:(item: T,index?:number) => boolean):T[] { 
//   const result = [];
//   for (let i = 0; i < arr.length; i++) {
//     const item = arr[i];
//     if (callback(item)) {
//       result.push(item);
//     }
//   }
//   return result;
// }
// const filterArr2 = filter(["xxx.js","aaa.java","bbb.md"], item => item.endsWith(".js"));
// console.log(filterArr2);

type Filter<T> = (arr: T[], callback: (item: T, index?: number) => boolean) => T[];

const filter: Filter<number> = (arr, callback) => { 
  const result = [];
  for (let i = 0; i < arr.length; i++) {
    const item = arr[i];
    if (callback(item)) {
      result.push(item);
    }
  }
  return result;
}

const filterArr2 = filter([1, 2, 3, 4, 5], item => item % 2 === 0);

// add
// function add<T>(a: T, b: T) { 
//   return a + b;
// }

type Add<T> = (a: T, b: T) => T;

const add: Add<string> = (a, b) => a + b;